/**   
 * 项目名：五位一体化工安全信息平台
 * 日期：    2019-12-06 09:51:29  
 * Copyright (c) 2015- joysuch-版权所有     
 */

package com.joysuch.wwyt.bp.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.transaction.Transactional;

import com.joysuch.wwyt.bp.bean.BpRegulationDocumentTypeAddBean;
import com.joysuch.wwyt.bp.bean.BpRegulationDocumentTypeEditBean;
import com.joysuch.wwyt.bp.bean.BpRegulationDocumentTypeListBean;
import com.joysuch.wwyt.bp.entity.BpRegulationDocumentType;
import com.joysuch.wwyt.bp.entity.dsl.QBpRegulationDocument;
import com.joysuch.wwyt.bp.entity.risk.BpJudgeDepart;
import com.joysuch.wwyt.bp.repository.BpRegulationDocumentDao;
import com.joysuch.wwyt.bp.repository.BpRegulationDocumentTypeDao;
import com.joysuch.wwyt.bp.service.BpRegulationDocumentTypeService;
import com.joysuch.wwyt.core.service.BizCodeGeneratorFacade;
import org.activiti.bpmn.model.FlowElement;
import org.apache.shiro.util.Assert;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

@Service
@Transactional
public class BpRegulationDocumentTypeServiceImpl implements BpRegulationDocumentTypeService {

    @Autowired
    private BpRegulationDocumentTypeDao dao;
    @Autowired
    private BpRegulationDocumentDao documentDao;
    @Autowired
    private BizCodeGeneratorFacade bizCodeGeneratorFacade;

    @Override
    public void add(BpRegulationDocumentTypeAddBean regDocTypeAdd) throws Exception {
        BpRegulationDocumentType bpRegulationDocumentType = new BpRegulationDocumentType();
        bpRegulationDocumentType.setName(regDocTypeAdd.getName());
        bpRegulationDocumentType.setDocumentCount(0);
        dao.save(bpRegulationDocumentType);
    }

    @Override
    public void update(BpRegulationDocumentTypeEditBean regDocTypeEdit) throws Exception {
        BpRegulationDocumentType content = dao.findById(regDocTypeEdit.getId()).get();
        if (content != null) {
            content.setName(regDocTypeEdit.getName());
            content.setDocumentCount(regDocTypeEdit.getDocumentCount() == null ? 0 : regDocTypeEdit.getDocumentCount());
            dao.save(content);
        }
    }

    @Override
    public Page<BpRegulationDocumentType> findByPage(Pageable page, String docCode) {
        // page = PageDataUtils.addOrderByDesc(page, "documentCount");
        Specification<BpRegulationDocumentType> specification = new Specification<BpRegulationDocumentType>() {
            @Override
            public Predicate toPredicate(Root<BpRegulationDocumentType> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb) {
                List<Predicate> predicates = new ArrayList<>();
                if (docCode != null) {
                    predicates.add(cb.equal(root.get("docCode"), docCode));
                }
                return cb.and(predicates.toArray(new Predicate[predicates.size()]));
            }
        };
        return dao.findAll(specification,page);
        //return dao.findAll(page);

    }

    @Override
    public void delete(Long id) {
        long count = documentDao.count(QBpRegulationDocument.bpRegulationDocument.documentTypeId.eq(id));
        Assert.isTrue(count == 0, "文档类型下存在文档，不能删除");
        dao.deleteById(id);
    }

    @Override
    public BpRegulationDocumentType findById(Long id) {
        return dao.findById(id).get();
    }

    @Override
    public List<BpRegulationDocumentTypeListBean> findAll(String docCode) {
        List<BpRegulationDocumentType> all = dao.findAllByDocCodeOrderByNameAsc(docCode);
        List<BpRegulationDocumentTypeListBean> allList = new ArrayList<>();
        for (BpRegulationDocumentType temp : all) {
            BpRegulationDocumentTypeListBean bean = new BpRegulationDocumentTypeListBean();
            bean.setValue(temp.getId());
            bean.setLabel(temp.getName());
            bean.setDocumentCount(temp.getDocumentCount());
            allList.add(bean);
        }
        return allList;
    }

    @Override
    public void documentCountOption(Long id, boolean isUp) {
        BpRegulationDocumentType content = dao.findById(id).get();
        if (content != null) {
            int tempCount = content.getDocumentCount().intValue();
            if (isUp) {
                content.setDocumentCount(++tempCount);
            } else {
                content.setDocumentCount(--tempCount);
            }
            dao.save(content);
        }
    }

    @Override
    public boolean checkName(String name,String docCode) {
        int count = dao.countByNameAndDocCode(name,docCode);
        return count > 0 ? true : false;
    }

    @Override
    public void save(List<Map<String, Object>> docTypeList, String docCode) {
        List<BpRegulationDocumentTypeListBean> sourceDocTypeList = findAll(docCode);
        List<Long> ids = new ArrayList<>();
        for (Map<String, Object> tempMap : docTypeList) {
            // 循环获取待操作的文档类型数组
            if (tempMap.containsKey("id")) { // 如果有 ID ，则修改
                // 记录操作过的 ID ，用于之后的删除判断
                Long tempId = Long.parseLong(tempMap.get("id").toString());
                ids.add(tempId);
                for (BpRegulationDocumentTypeListBean tempBean : sourceDocTypeList) {
                    // 循环获取原文档类型对象
                    if (tempId.equals(tempBean.getValue())) {
                        // 如果该文档类型下没有文档，并且没有重复名称的文档类型，则进行修改
                        if (tempBean.getDocumentCount() <= 0 && !checkName(tempMap.get("label").toString(),docCode)) {
                            // 进行修改操作
                            BpRegulationDocumentType tempDocType = findById(tempId);
                            tempDocType.setName(tempMap.get("label").toString());
                            tempDocType.setDocCode(docCode);
                            dao.save(tempDocType);
                        }
                    }
                }
            } else { // 没有 ID，则新增
                // if (!checkName(tempMap.get("label").toString())) { // 如果文档类型名称不重复，则添加
                // 进行添加操作
                BpRegulationDocumentType tempDocTypeAdd = new BpRegulationDocumentType();
                tempDocTypeAdd.setName(tempMap.get("label").toString());
                tempDocTypeAdd.setDocumentCount(0);
                tempDocTypeAdd.setDocCode(docCode);
                Assert.isTrue(!checkName(tempMap.get("label").toString(),docCode),
                        String.format("文档类型【%s】已存在", tempMap.get("label") + ""));
                dao.save(tempDocTypeAdd);
                // }
            }
        }
        // 如果传入的 ID 小于 原文档类型数量，进行删除操作
        if (ids.size() < sourceDocTypeList.size()) {
            // 筛选出需要删除的对象
            List<BpRegulationDocumentTypeListBean> deleteList = sourceDocTypeList;
            for (int i = 0; i < sourceDocTypeList.size(); i++) {
                for (Long itemId : ids) {
                    if (sourceDocTypeList.get(i).getValue().equals(itemId)) {
                        deleteList.remove(i);
                    }
                }
            }
            if (deleteList.size() > 0) {
                for (BpRegulationDocumentTypeListBean tempDelet : deleteList) {
                    // 如果该文档类型下没有文档，则进行删除操作
                    if (tempDelet.getDocumentCount() <= 0) {
                        // 进行删除操作
                        delete(tempDelet.getValue());
                    }
                }
            }
        }

    }

    @Override
    public void updateTypeDocumentCount(Long id) {
        dao.updateDocumentCount(id);
    }

    @Override
    public List<Long> getTypeIdByDocCode(String docCode) {
        List<BpRegulationDocumentType> typeList = dao.findAllByDocCodeOrderByNameAsc(docCode);
        if(typeList == null){
            return new ArrayList<>();
        }
        return typeList.stream().map(BpRegulationDocumentType::getId).collect(Collectors.toList());
    }
}
